home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / DB.PAK / DBPPG.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  12KB  |  469 lines

  1. // dbppg.cpp : Implementation of the CDbPropPage property page class.
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1995 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include "stdafx.h"
  14. #include "db.h"
  15. #include "dbppg.h"
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char BASED_CODE THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22.  
  23. IMPLEMENT_DYNCREATE(CDbPropPage, COlePropertyPage)
  24.  
  25. #define STR_LEN 128+1
  26.  
  27.  
  28.  
  29. /////////////////////////////////////////////////////////////////////////////
  30. // Message map
  31.  
  32. BEGIN_MESSAGE_MAP(CDbPropPage, COlePropertyPage)
  33.     //{{AFX_MSG_MAP(CDbPropPage)
  34.     ON_CBN_SELCHANGE(IDC_DATASOURCE, OnSelchangeDatasource)
  35.     ON_CBN_SELCHANGE(IDC_COLUMNS, OnSelchangeColumns)
  36.     ON_CBN_SELCHANGE(IDC_TABLES, OnSelchangeTables)
  37.     //}}AFX_MSG_MAP
  38. END_MESSAGE_MAP()
  39.  
  40.  
  41. /////////////////////////////////////////////////////////////////////////////
  42. // Initialize class factory and guid
  43.  
  44. IMPLEMENT_OLECREATE_EX(CDbPropPage, "DB.DbPropPage.1",
  45.     0xeff01749, 0x7825, 0x101b, 0x83, 0x75, 0x0, 0xaa, 0x0, 0x37, 0x3f, 0xb9)
  46.  
  47.  
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CDbPropPage::CDbPropPageFactory::UpdateRegistry -
  50. // Adds or removes system registry entries for CDbPropPage
  51.  
  52. BOOL CDbPropPage::CDbPropPageFactory::UpdateRegistry(BOOL bRegister)
  53. {
  54.     if (bRegister)
  55.         return AfxOleRegisterPropertyPageClass(AfxGetInstanceHandle(),
  56.             m_clsid, IDS_DB_PPG);
  57.     else
  58.         return AfxOleUnregisterClass(m_clsid, NULL);
  59. }
  60.  
  61.  
  62. /////////////////////////////////////////////////////////////////////////////
  63. // CDbPropPage::CDbPropPage - Constructor
  64.  
  65. CDbPropPage::CDbPropPage() :
  66.     COlePropertyPage(IDD, IDS_DB_PPG_CAPTION)
  67. {
  68.     //{{AFX_DATA_INIT(CDbPropPage)
  69.     m_dataSource = _T("");
  70.     m_columnName = _T("");
  71.     m_tableName = _T("");
  72.     //}}AFX_DATA_INIT
  73. }
  74.  
  75.  
  76. /////////////////////////////////////////////////////////////////////////////
  77. // CDbPropPage::DoDataExchange - Moves data between page and properties
  78.  
  79. void CDbPropPage::DoDataExchange(CDataExchange* pDX)
  80. {
  81.     //{{AFX_DATA_MAP(CDbPropPage)
  82.     DDP_CBString(pDX, IDC_DATASOURCE, m_dataSource, _T("DataSource") );
  83.     DDX_CBString(pDX, IDC_DATASOURCE, m_dataSource);
  84.     DDP_CBString(pDX, IDC_TABLES, m_tableName, _T("TableName") );
  85.     DDX_CBString(pDX, IDC_TABLES, m_tableName);
  86.     DDP_CBString(pDX, IDC_COLUMNS, m_columnName, _T("ColumnName") );
  87.     DDX_CBString(pDX, IDC_COLUMNS, m_columnName);
  88.     //}}AFX_DATA_MAP
  89.     DDP_PostProcessing(pDX);
  90. }
  91.  
  92.  
  93. /////////////////////////////////////////////////////////////////////////////
  94. // CDbPropPage message handlers
  95.  
  96. BOOL CDbPropPage::OnInitDialog() 
  97. {
  98.     COlePropertyPage::OnInitDialog();
  99.  
  100.     UCHAR         szSourceName[SQL_MAX_DSN_LENGTH+1];
  101.     UCHAR         szDescription[255];
  102.     SWORD        swDLength;
  103.     SWORD        swSLength;
  104.     RETCODE     rCode;
  105.     HENV         hEnv;
  106.     CComboBox    *pDSNCombo = (CComboBox *) GetDlgItem(IDC_DATASOURCE);
  107.     CComboBox    *pTablesCombo = (CComboBox *) GetDlgItem(IDC_TABLES);
  108.     CComboBox    *pColumnsCombo = (CComboBox *) GetDlgItem(IDC_COLUMNS);
  109.  
  110.     pDSNCombo->EnableWindow(FALSE);
  111.     pTablesCombo->EnableWindow(FALSE);
  112.     pColumnsCombo->EnableWindow(FALSE);
  113.  
  114.     if (SQLAllocEnv(&hEnv) != SQL_SUCCESS)
  115.     {
  116.         MessageBox("Couldn't allocate HENV!");
  117.         return FALSE;
  118.     }
  119.  
  120.     rCode = SQLDataSources(hEnv, SQL_FETCH_FIRST, szSourceName,
  121.             SQL_MAX_DSN_LENGTH, &swSLength, szDescription,
  122.             sizeof(szDescription), &swDLength);
  123.  
  124.     if (rCode != SQL_ERROR && rCode != SQL_NO_DATA_FOUND)
  125.        {
  126.         do {
  127.             pDSNCombo->AddString((char *) szSourceName);
  128.  
  129.             rCode = SQLDataSources(hEnv, SQL_FETCH_NEXT, szSourceName,
  130.                 SQL_MAX_DSN_LENGTH, &swSLength, szDescription, sizeof(szDescription), &swDLength);
  131.            }
  132.         while (rCode != SQL_ERROR && rCode != SQL_NO_DATA_FOUND);
  133.        }
  134.      
  135.     SQLFreeEnv(hEnv);
  136.     
  137.     if (pDSNCombo->GetCount() > 0)
  138.     {
  139.         pDSNCombo->EnableWindow();
  140.  
  141.         if (!m_dataSource.IsEmpty())
  142.             if (pDSNCombo->SelectString(-1, m_dataSource) == CB_ERR)
  143.                 m_dataSource.Empty();
  144.             else
  145.                 OnSelchangeDatasource();
  146.     }
  147.  
  148.     return FALSE;  // return TRUE unless you set the focus to a control
  149.                   // EXCEPTION: OCX Property Pages should return FALSE
  150. }
  151.  
  152.  
  153. void ODBCErrorBox(CWnd* pParent, HENV hEnv, HDBC hDBC)
  154. {
  155.     UCHAR    szState[SQL_MAX_MESSAGE_LENGTH];
  156.     UCHAR    szError[SQL_MAX_MESSAGE_LENGTH];
  157.     SDWORD    dwError;
  158.     SWORD    wErrorLen;
  159.     CString    strMessage;
  160.                 
  161.     SQLError(hEnv, hDBC, SQL_NULL_HSTMT, szState, &dwError, szError,
  162.         SQL_MAX_MESSAGE_LENGTH-1, &wErrorLen);
  163.     strMessage = (LPSTR) szState;
  164.     strMessage += ": ";
  165.     strMessage += (LPSTR) szError;
  166.         
  167.     if (pParent == NULL)
  168.         ::MessageBox(NULL, (LPSTR) szError, "ODBC Error!", MB_OK);
  169.     else
  170.         pParent->MessageBox((LPSTR) szError, "ODBC Error!");
  171.     
  172.     return;
  173. }
  174.  
  175. static int GetDriverLevel(HDBC hdbc)
  176. {
  177.     WORD    wLevel;
  178.     
  179.     SQLGetInfo(hdbc,
  180.         SQL_ODBC_API_CONFORMANCE,
  181.         (PTR)&wLevel,
  182.         sizeof(wLevel),
  183.         NULL);
  184.     
  185.     return (int) wLevel;
  186. }
  187.  
  188.  
  189. void CDbPropPage::OnSelchangeDatasource() 
  190. {
  191.     HENV        henv;
  192.     HDBC        hdbc;
  193.     HSTMT        hstmt;
  194.     RETCODE        retcode;
  195.     CComboBox    *psColumns = (CComboBox *) GetDlgItem(IDC_COLUMNS);
  196.     CComboBox    *psBox = (CComboBox *) GetDlgItem(IDC_DATASOURCE);
  197.     CComboBox    *psTables = (CComboBox *) GetDlgItem(IDC_TABLES);
  198.     int            nSelected;
  199.     char        szOwner[STR_LEN];
  200.     char        szTableName[STR_LEN];
  201.     UCHAR        szSource[STR_LEN];
  202.     UCHAR        szBrowseResult[STR_LEN];
  203.     SDWORD        cbOwner, cbName;
  204.     
  205.     nSelected = psBox->GetCurSel();
  206.     if (nSelected == CB_ERR)
  207.         return;
  208.         
  209.     psBox->GetLBText(nSelected, m_dataSource);
  210.     strcpy((LPSTR) szSource, m_dataSource);
  211.  
  212.     retcode = SQLAllocEnv(&henv);              /* Environment handle */
  213.     
  214.     if (retcode == SQL_SUCCESS)
  215.     {
  216.         retcode = SQLAllocConnect(henv, &hdbc); /* Connection handle */
  217.         if (retcode == SQL_SUCCESS)
  218.         {
  219.             BOOL bNeedID = FALSE;
  220.             
  221.             if (GetDriverLevel(hdbc) == 2)
  222.             {
  223.                 SWORD    cbBrowse;
  224.                 UCHAR    szSourceInfo[256];
  225.                 
  226.                 cbBrowse = STR_LEN;
  227.                 strcpy((LPSTR) szSourceInfo, "DSN=");
  228.                 strcat((LPSTR) szSourceInfo, m_dataSource);
  229.                 
  230.                 SQLBrowseConnect(hdbc, szSourceInfo, SQL_NTS,
  231.                          szBrowseResult, STR_LEN, &cbBrowse); 
  232.  
  233.                 MessageBox((LPSTR) szBrowseResult);
  234.                 if (strstr((LPCSTR) szBrowseResult, "PWD") != NULL)
  235.                 {
  236.                     bNeedID = TRUE;
  237.                 }
  238.             }
  239.             
  240.             GetDlgItem(ID_USERNAME)->EnableWindow(bNeedID);
  241.             GetDlgItem(ID_PASSWORD)->EnableWindow(bNeedID);
  242.  
  243.      // Set login timeout to 15 seconds
  244.  
  245.             SQLSetConnectOption(hdbc, SQL_LOGIN_TIMEOUT, 15);
  246.  
  247.     // Connect to data source
  248.                                        
  249.             retcode = SQLConnect(hdbc, szSource, SQL_NTS,
  250.                                     NULL, SQL_NTS, NULL, SQL_NTS);
  251.  
  252.             if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
  253.             {
  254.  
  255.     // try to get a list of tables
  256.  
  257.                 retcode = SQLAllocStmt(hdbc, &hstmt); /* Statement handle */
  258.                  if (retcode == SQL_SUCCESS)
  259.                 {
  260.                     retcode = SQLTables(hstmt,
  261.                                 NULL, 0,    // all qualifiers
  262.                                 NULL, 0,    // all owners
  263.                                 NULL, 0,    // all tables
  264.                                 NULL, 0);    // all types
  265.                                 
  266.                     if (retcode == SQL_SUCCESS)
  267.                     {
  268.                         SQLBindCol(hstmt, 2, SQL_C_CHAR, szOwner, STR_LEN, &cbOwner);
  269.                         SQLBindCol(hstmt, 3, SQL_C_CHAR, szTableName, STR_LEN, &cbName);
  270.                                     
  271.                         psTables->ResetContent();
  272.                         psColumns->ResetContent();
  273.                         psColumns->EnableWindow(FALSE);
  274.                         BOOL bAddedOne = FALSE;
  275.                         
  276.                         while (TRUE)
  277.                         {
  278.                             retcode = SQLFetch(hstmt);
  279.                             
  280.                             if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
  281.                             {
  282.                                 CString strAdd;
  283.                                 
  284.                                 if (lstrlen(szOwner) != 0)
  285.                                 {
  286.                                     strAdd = szOwner;
  287.                                     strAdd += ".";
  288.                                 }
  289.                                 strAdd += szTableName;
  290.                                 
  291.                                 psTables->AddString(strAdd);
  292.                                 bAddedOne = TRUE;
  293.                             }
  294.                             else
  295.                             {
  296.                                 break;
  297.                             }
  298.                         }
  299.                         
  300.                         psTables->EnableWindow(bAddedOne);
  301.                     }
  302.                     else
  303.                     {
  304.                         ODBCErrorBox(this, henv, hdbc);
  305.                     }
  306.  
  307.                     SQLFreeStmt(hstmt, SQL_DROP);
  308.                 }
  309.                 
  310.                 SQLDisconnect(hdbc);
  311.             }
  312.             else
  313.             {
  314.                 ODBCErrorBox(this, henv, hdbc);
  315.             }
  316.  
  317.             SQLFreeConnect(hdbc);
  318.         }
  319.         SQLFreeEnv(henv);
  320.     }
  321.     
  322.     return;
  323. }
  324.  
  325. void CDbPropPage::OnSelchangeColumns() 
  326. {
  327.     return;
  328. }
  329.  
  330. void CDbPropPage::OnSelchangeTables() 
  331. {
  332.     CComboBox    *psTables = (CComboBox *) GetDlgItem(IDC_TABLES);
  333.     CComboBox    *psColumns = (CComboBox *) GetDlgItem(IDC_COLUMNS);
  334.     int         nSelected;
  335.     HENV        henv;
  336.     HDBC        hdbc;
  337.     HSTMT        hstmt;
  338.     RETCODE        retcode;
  339.     BOOL        bAddedOne;
  340.     UCHAR        szSource[256];
  341.     UCHAR        szSelectedTable[256];
  342.     UCHAR        szSelectedOwner[256];
  343.     char        szColumnName[STR_LEN];
  344.     SDWORD        cbColumnName;
  345.     LPSTR        pstrTrim;
  346.     BOOL        bHasOwner;
  347.  
  348.  
  349.     nSelected = psTables->GetCurSel();
  350.     if (nSelected == CB_ERR)
  351.         return;
  352.  
  353.     psTables->GetLBText(nSelected, (char *) szSelectedTable);
  354.     m_tableName = (char*) szSelectedTable;
  355.     
  356.     pstrTrim = strchr((LPSTR) szSelectedTable, '.');
  357.     if (pstrTrim != NULL)
  358.     {
  359.         *pstrTrim = '\0';
  360.         strcpy((LPSTR) szSelectedOwner, (LPSTR) szSelectedTable);
  361.         strcpy((LPSTR) szSelectedTable, pstrTrim+1);
  362.         bHasOwner = TRUE;
  363.     }
  364.     else
  365.     {
  366.         bHasOwner = FALSE;
  367.     }
  368.     strcpy((LPSTR) szSource, m_dataSource);
  369.  
  370.     retcode = SQLAllocEnv(&henv);              // Environment handle
  371.     if (retcode == SQL_SUCCESS)
  372.     {
  373.         retcode = SQLAllocConnect(henv, &hdbc); // Connection handle
  374.         if (retcode == SQL_SUCCESS)
  375.         {
  376.  
  377.      // Set login timeout to 15 seconds
  378.  
  379.             SQLSetConnectOption(hdbc, SQL_LOGIN_TIMEOUT, 15);
  380.  
  381.     // Connect to data source
  382.                                        
  383.             retcode = SQLConnect(hdbc, szSource, SQL_NTS,
  384.                                     NULL, SQL_NTS, NULL, SQL_NTS);
  385.             
  386.             if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
  387.             {
  388.                 // try to get a list of columns for the table
  389.  
  390.                 retcode = SQLAllocStmt(hdbc, &hstmt);        // Statement handle
  391.                  if (retcode == SQL_SUCCESS)
  392.                 {
  393.                     if (bHasOwner == TRUE)
  394.                     {
  395.                         retcode = SQLColumns(hstmt,
  396.                             NULL, 0,    // no table qualifier
  397.                             szSelectedOwner, SQL_NTS,    // specified owner
  398.                             szSelectedTable, SQL_NTS,    // selected table 
  399.                             NULL, 0        // no pattern
  400.                             );
  401.                     }
  402.                     else
  403.                     {
  404.                         retcode = SQLColumns(hstmt,
  405.                             NULL, 0,    // no table qualifier
  406.                             NULL, 0,    // no table owner
  407.                             szSelectedTable, SQL_NTS,    // selected table 
  408.                             NULL, 0        // no pattern
  409.                             );
  410.                     }
  411.                 
  412.                     if (retcode == SQL_SUCCESS)
  413.                     {
  414.                         SQLBindCol(hstmt, 4, SQL_C_CHAR, szColumnName, STR_LEN, &cbColumnName);
  415.                         
  416.                         psColumns->ResetContent();
  417.                         bAddedOne = FALSE;
  418.                         
  419.                         while (TRUE)
  420.                         {
  421.                             retcode = SQLFetch(hstmt);
  422.                             
  423.                             if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
  424.                             {
  425.                                 psColumns->AddString(szColumnName);
  426.                                 bAddedOne = TRUE;
  427.                             }
  428.                             else
  429.                             {
  430.                                 break;
  431.                             }
  432.                         }
  433.                         
  434.                         psColumns->EnableWindow(bAddedOne);
  435.                     }
  436.                     else
  437.                     {
  438.                         ODBCErrorBox(this, henv, hdbc);
  439.                     }
  440.  
  441.                     SQLFreeStmt(hstmt, SQL_DROP);
  442.                 }
  443.                 else
  444.                 {
  445.                     ODBCErrorBox(this, henv, hdbc);
  446.                 }
  447.  
  448.                 SQLDisconnect(hdbc);
  449.             }
  450.             else
  451.             {
  452.                 ODBCErrorBox(this, henv, hdbc);
  453.             }
  454.  
  455.             SQLFreeConnect(hdbc);
  456.         }
  457.         SQLFreeEnv(henv);
  458.     }
  459.  
  460.     if (psTables->GetCurSel() != CB_ERR)
  461.     {
  462.         psColumns->EnableWindow(TRUE);
  463.     }
  464.     else
  465.     {
  466.         psColumns->EnableWindow(TRUE);
  467.     }    
  468. }
  469.